package com.lmx.persistence.service;

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Properties;

import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import com.google.common.collect.Maps;
import com.lmx.common.constants.CommonConstants;
import com.lmx.common.constants.LeaveStatus;
import com.lmx.common.context.ActionContextHolder;
import com.lmx.common.util.CommonUtil;
import com.lmx.common.util.PropertiesFileUtil;
import com.lmx.repoDomain.exception.BusinessException;
import com.lmx.repoDomain.tmodel.Customer;
import com.lmx.repoDomain.tmodel.CustomerActivityCompareService;
import com.lmx.repoDomain.tmodel.CustomerActivityPlan;
import com.lmx.repoDomain.tmodel.CustomerActivityPlanExecute;
import com.lmx.repoDomain.tmodel.CustomerActivityPlanModel;
import com.lmx.repoDomain.tmodel.CustomerActivityPlanServiceItem;
import com.lmx.repoDomain.tmodel.CustomerActivityPlanServiceItemDetail;
import com.lmx.repoDomain.tmodel.CustomerActivityProjectItem;
import com.lmx.repoDomain.tmodel.CustomerActivityServiceItem;
import com.lmx.repoDomain.tmodel.CustomerLeave;
import com.lmx.repoDomain.tmodel.CustomerNursingPlan;
import com.lmx.repoDomain.tmodel.Employee;
import com.lmx.repoDomain.tmodel.NursingProjectServiceItem;
import com.lmx.repoDomain.tmodel.ServiceFinishLevel;

/**
 *
 *
 * @author huibati
 * @version 1.00
 */
@Service
@Scope("prototype")
public class CustomerActivityService<T> {

	private Log logger = LogFactory.getLog(this.getClass());

	private Properties properties = PropertiesFileUtil.getApplicationProperties();

	@PersistenceContext
	private EntityManager em;

	@Autowired
	protected GenericService dslJpaService;

	@Autowired
	protected UserService userService;

	@Autowired
	protected CommonService commonService;

	/**
	 * 获取护工单前所需完成的projectitem 不定时任务
	 */
	public Iterable<CustomerActivityProjectItem> getStaffProjectItem(long userId) {
		// Role role = userService.getRoleByUserId(userId);//获取user对应角色
		List<CustomerActivityProjectItem> itemList = new ArrayList<CustomerActivityProjectItem>();
		// huibati 获取 user所对应 employee 在获取 employee所对应customer
		StringBuilder queryCustomer = new StringBuilder(
				"select c from Customer c where c.delStatus != 1 and c.customerStatus is not null and ( c.customerStatus.typecode=?3 or c.customerStatus.typecode=?4 or c.customerStatus.typecode=?5 ) "
						+ " and c.bed in ( select b from Bed b where b.delStatus != ?1 "
						+ " and b in( select n.bed from BedNurseGroup n where n.delStatus != ?1 "
						+ " and n.group in( select c.group from EmployeeNursingGroup c where c.delStatus != 1 and c.employee in (select u.employee from User u where u.id = ?2 )) "
						+ "))");
		List<Customer> customerList = this.em.createQuery(queryCustomer.toString())
				.setParameter(1, (short) 1).setParameter(2, userId)
				.setParameter(3, "customerStatusIn").setParameter(4, "customerStatusTry")
				.setParameter(5, "customerStatusTryWaitIn").getResultList();
		if (customerList.size() > 0) {
			// 获取当前护工所护理老人对应的 NursingProjectServiceItem 通过角色类型进行过滤
			StringBuilder queryItem = new StringBuilder(
					"select item from CustomerActivityProjectItem item JOIN FETCH item.project project "
							+ "where item.delStatus != ?1 and project.customer in(:olds) ");
			itemList = this.em.createQuery(queryItem.toString())
					.setParameter(1, (short) 1).setParameter("olds", customerList).getResultList();
		}
		return itemList;
	}

	/**
	 * 摘取数据
	 */

	public List getCustomersFromCustomerNursingPlan(CustomerActivityPlan record) {
		// 删除原有数据
		List customers = new ArrayList<>();
		if (record.getDetails() != null && record.getDetails().size() > 0) {
			for (CustomerActivityPlanServiceItemDetail detail : record.getDetails()) {
				if (customers.contains(detail.getCustomer())) {

				} else {
					customers.add(detail.getCustomer());
				}
			}
		}
		return customers;
	}

	/**
	 * 删除日护理计划 （日计划或者周计划）
	 */
	@Transactional
	public void deletePlanDayDetailByRecord(CustomerActivityPlan record) {
		// 删除原有数据
		List customers = new ArrayList<>();
		if (record.getCustomers() != null && !"".equals(record.getCustomers())) {
			String[] ids = record.getCustomers().split(",");
			for (String id : ids) {
				if (!"".equals(id)) {
					customers.add(Long.valueOf(id));
				}
			}
		}
		Integer weekTab = record.getWeekTab();
		String periodType = "";
		if ("month".equals(record.getItemType())) {
			periodType = "periodMonth";
		}
		if ("week".equals(record.getItemType())) {
			periodType = "periodWeek";
		}
		if ("day".equals(record.getItemType())) {
			periodType = "periodDay";
		}
		if (customers != null && customers.size() > 0) {
			List<CustomerActivityPlanServiceItemDetail> dataList = new ArrayList<>();
			StringBuilder queryDetail = new StringBuilder(
					"select  c from  CustomerActivityPlanServiceItemDetail c where c.customer is not null  "
							+ " and c.customer.id in (:olds) "
							+ " and ( c.yearTab=?1 and c.weekIndex=?2 and c.weekTab=?3 "
							+ " and c.item.item.period.typecode=?4)");
			dataList = this.em.createQuery(queryDetail.toString())
					.setParameter(1, record.getYearTab()).setParameter(2, record.getWeekIndex())
					.setParameter(3, weekTab).setParameter(4, periodType)
					.setParameter("olds", customers).getResultList();
			if (dataList.size() > 0) {
				StringBuilder query = new StringBuilder(
						" delete from  CustomerActivityPlanServiceItemDetail c where c in (:dataList) ");
				this.em.createQuery(query.toString()).setParameter("dataList", dataList)
						.executeUpdate();
			}
		}
	}

	/**
	 * 删除护理计划 记录当天所有计划
	 */
	@Transactional
	public void deletePlanDetailByRecord(CustomerNursingPlan record) {
		// 删除原有数据
		// List customers = getCustomersFromCustomerNursingPlan(record);
		List customers = new ArrayList<>();
		if (record.getCustomers() != null && !"".equals(record.getCustomers())) {
			String[] ids = record.getCustomers().split(",");
			for (String id : ids) {
				if (!"".equals(id)) {
					customers.add(Long.valueOf(id));
				}
			}
		}
		Date now = new Date();
		Integer weekTab = CommonUtil.getWeek(now);
		if (weekTab == 0)
			weekTab = 7;
		int weekIndex = CommonUtil.getWeekIndexFromSun(now);
		if (customers != null && customers.size() > 0) {
			StringBuilder query = new StringBuilder(
					"delete from  NursingPlanDetail c where c.customer is not null "
							+ "and c.customer.id in (:olds) ");
			// 验证是所传周是不是当前周 是的话今天以前几天数据不删
			if (weekIndex == record.getWeekIndex()) {// 当前周
				query.append(" and ( c.yearTab=?1 and c.weekIndex=?2 and c.weekTab>?3) ");
				this.em.createQuery(query.toString()).setParameter(1, record.getYearTab())
						.setParameter(2, record.getWeekIndex()).setParameter(3, weekTab)
						.setParameter("olds", customers).executeUpdate();
			} else {// 以后几周
				query.append(" and ( c.yearTab=?1 and c.weekIndex=?2 ) ");
				this.em.createQuery(query.toString()).setParameter(1, record.getYearTab())
						.setParameter(2, record.getWeekIndex()).setParameter("olds", customers)
						.executeUpdate();
			}
		}
	}

	/**
	 * 删除护理计划 未来几周
	 */
	@Transactional
	public void deletePlanDetailNextWeeks(CustomerNursingPlan record, int weekNum) {
		// 删除原有数据
		// List customers = getCustomersFromCustomerNursingPlan(record);
		List customers = new ArrayList<>();
		if (record.getCustomers() != null && !"".equals(record.getCustomers())) {
			String[] ids = record.getCustomers().split(",");
			for (String id : ids) {
				if (!"".equals(id)) {
					customers.add(Long.valueOf(id));
				}
			}
		}
		if (customers != null && customers.size() > 0) {
			Map<Integer, String> dateTab = new HashMap<>();
			dateTab.put(0, record.getYearTab() + "," + record.getWeekIndex());
			for (Integer i = 0; i < weekNum + 1; i++) {
				if (i > 0) {
					Integer yearTab = Integer.valueOf(dateTab.get(i - 1).split(",")[0]);
					Integer weekIndex = Integer.valueOf(dateTab.get(i - 1).split(",")[1]) + 1;
					if (weekIndex > 52) {
						weekIndex = 1;
						yearTab++;
					}
					dateTab.put(i, yearTab + "," + weekIndex);
				}
			}
			StringBuilder query = new StringBuilder(
					"delete from  NursingPlanDetail c where c.customer is not null "
							+ "and c.customer.id in (:olds) " + "and " + " ("
							+ " ( c.yearTab=?1 and c.weekIndex=?2 ) or"
							+ " ( c.yearTab=?3 and c.weekIndex=?4 ) or"
							+ " ( c.yearTab=?5 and c.weekIndex=?6 ) or"
							+ " ( c.yearTab=?7 and c.weekIndex=?8 ) " + " )");
			Integer t = Integer.valueOf(dateTab.get(1).split(",")[0]);
			this.em.createQuery(query.toString()).setParameter(1, record.getYearTab())
					.setParameter(2, record.getWeekIndex()).setParameter(3, t)
					.setParameter(4, Integer.valueOf(dateTab.get(1).split(",")[1]))
					.setParameter(5, Integer.valueOf(dateTab.get(2).split(",")[0]))
					.setParameter(6, Integer.valueOf(dateTab.get(2).split(",")[1]))
					.setParameter(7, Integer.valueOf(dateTab.get(3).split(",")[0]))
					.setParameter(8, Integer.valueOf(dateTab.get(3).split(",")[1]))
					.setParameter("olds", customers).executeUpdate();
		}
	}

	/**
	 * 删除未来四周护理计划
	 */
	@Transactional
	public void deletePlanDetailNextWeeksByCustomer(Customer customer, int weekNum) {
		// 删除原有数据
		if (weekNum > 0 && customer != null) {
			Map<Integer, String> dateTab = new HashMap<>();
			int yearNow = (new Date().getYear() + 1900);
			int weekIndexNow = CommonUtil.getWeekIndexFromSun(new Date());// 以周末为第一天当前是第几周
			if (weekIndexNow + 1 > 52) {
				dateTab.put(0, (yearNow + 1) + "," + 1);
			} else {
				dateTab.put(0, yearNow + "," + (weekIndexNow + 1));
			}
			for (Integer i = 0; i < weekNum; i++) {
				if (i > 0) {
					Integer yearTab = Integer.valueOf(dateTab.get(i - 1).split(",")[0]);
					Integer weekIndex = Integer.valueOf(dateTab.get(i - 1).split(",")[1]) + 1;
					if (weekIndex > 52) {
						weekIndex = 1;
						yearTab++;
					}
					dateTab.put(i, yearTab + "," + weekIndex);
				}
			}
			StringBuilder query = new StringBuilder(
					"delete from  NursingPlanDetail c where c.customer is not null "
							+ "and c.customer.id =?9  " + "and ("
							+ " ( c.yearTab=?1 and c.weekIndex=?2 ) or "
							+ " ( c.yearTab=?3 and c.weekIndex=?4 ) or "
							+ " ( c.yearTab=?5 and c.weekIndex=?6 ) or "
							+ " ( c.yearTab=?7 and c.weekIndex=?8 ) " + "    )");
			this.em.createQuery(query.toString())
					.setParameter(1, Integer.valueOf(dateTab.get(0).split(",")[0]))
					.setParameter(2, Integer.valueOf(dateTab.get(0).split(",")[1]))
					.setParameter(3, Integer.valueOf(dateTab.get(1).split(",")[0]))
					.setParameter(4, Integer.valueOf(dateTab.get(1).split(",")[1]))
					.setParameter(5, Integer.valueOf(dateTab.get(2).split(",")[0]))
					.setParameter(6, Integer.valueOf(dateTab.get(2).split(",")[1]))
					.setParameter(7, Integer.valueOf(dateTab.get(3).split(",")[0]))
					.setParameter(8, Integer.valueOf(dateTab.get(3).split(",")[1]))
					.setParameter(9, customer.getId()).executeUpdate();
		}
	}

	/**
	 * 删除活动计划模版
	 */
	@Transactional
	public void deletePlanItemByCustomerId(Long customerId) {
		Date now = new Date();
		int yearNow = (now.getYear() + 1900);
		int weekIndexNow = CommonUtil.getWeekIndexFromSun(now);
		int weekTab = CommonUtil.getWeek(now);
		int deleteNowFlag = checkPlanDetailNowRelations(customerId, yearNow, weekIndexNow, weekTab);
		// 删除今天以后当周的活动计划
		StringBuilder queryNow = new StringBuilder(
				"delete from  CustomerActivityPlanServiceItemDetail c where c.customer is not null "
						+ " and c.customer.id =?1 and c.yearTab=?2 and ( c.weekIndex >?3  or ( c.weekIndex =?3 ");
		if (deleteNowFlag == 0) {
			queryNow.append(" and c.weekTab >=?4 ))");
		} else {
			queryNow.append(" and c.weekTab >?4 ))");
		}
		this.em.createQuery(queryNow.toString()).setParameter(1, customerId)
				.setParameter(2, yearNow).setParameter(3, weekIndexNow).setParameter(4, weekTab)
				.executeUpdate();
		// 删除原有模版
		StringBuilder query = new StringBuilder(
				"delete from  CustomerActivityPlanServiceItem c  where c.customer is not null and c.customer.id= ?1 ");
		this.em.createQuery(query.toString()).setParameter(1, customerId).executeUpdate();
	}

	/**
	 * 产生护理计划模版
	 */
	public void createPlanItem(CustomerActivityPlan record) {
		List dataList = new ArrayList<>();
		if (record.getDetails() != null && record.getDetails().size() != 0) {
			for (CustomerActivityPlanServiceItemDetail detail : record.getDetails()) {
				if (detail != null && detail.getDelStatus() != null && detail.getDelStatus() != 1) {
					CustomerActivityPlanServiceItem item = new CustomerActivityPlanServiceItem();
					item.setCustomer(detail.getCustomer());
					item.setDelStatus((short) 0);
					item.setItem(detail.getItem());
					item.setWeekTab(detail.getWeekTab());
					item.setMonthTab(detail.getMonthTab());
					item.setStartTimeTab(detail.getStartTimeTab());
					item.setTenant(detail.getCustomer().getTenant());
					dataList.add(item);
				}
			}
			if (dataList.size() > 0) {
				commonService.batchInsert(dataList);// 产生模版
			}
		}
	}

	/**
	 * 当天活动计划是否执行过
	 */
	public int checkPlanDetailNowRelations(Long customerId, int yearTab, int weekIndex, int weekTab) {
		StringBuilder queryNow = new StringBuilder(
				"select c from  CustomerActivityPlanExecute c where c.detail is not null and c.detail.customer is not null "
						+ " and c.detail.customer.id =?1 and c.detail.yearTab=?2 and c.detail.weekIndex =?3 and c.detail.weekTab =?4 ");
		List dataList = this.em.createQuery(queryNow.toString()).setParameter(1, customerId)
				.setParameter(2, yearTab).setParameter(3, weekIndex).setParameter(4, weekTab)
				.getResultList();
		if (dataList == null || dataList.size() == 0) {
			return 0;
		} else
			return dataList.size();
	}

	/**
	 * 复制当天活动计划
	 */
	public void copyPlanToday(CustomerActivityPlan record) {
		logger.debug("start CustomerActivityPlan copyPlanToday " + CommonUtil.getCurrTimeForString());
		List dataList = new ArrayList<>();
		Date dateTemp = new Date();
		if (record.getDetails() != null && record.getDetails().size() != 0) {
			for (CustomerActivityPlanServiceItemDetail detail : record.getDetails()) {
				if (detail != null && detail.getDelStatus() != null && detail.getDelStatus() != 1) {
					int weekIndex = CommonUtil.getWeekIndexFromSun(dateTemp);
					int monthIndex = dateTemp.getMonth();
					int monthTab = dateTemp.getDate();
					int year = dateTemp.getYear() + 1900;// 年 周 序号

					if (record.getYearTab() == year && record.getMonthIndex() == monthIndex
							&& record.getMonthTab() == monthTab) {
						CustomerActivityPlanServiceItemDetail data = new CustomerActivityPlanServiceItemDetail();
						data.setCreateDateTime(CommonUtil.getCurrTimes());
						data.setCustomer(detail.getCustomer());
						data.setItem(detail.getItem());
						data.setDelStatus((short) 0);
						data.setStartTimeTab(detail.getStartTimeTab());
						data.setTenant(detail.getCustomer().getTenant());
						data.setWeekTab(detail.getWeekTab());// 周几
						data.setWeekIndex(weekIndex);// 第几周
						data.setMonthIndex(monthIndex);
						data.setMonthTab(monthTab);
						data.setYearTab(year);
						dataList.add(data);
					}
				}
			}
			if (dataList.size() > 0) {
				commonService.batchInsert(dataList);
			}
		}
	}

	/**
	 * 按照星期 复制护理计划
	 */
	public void copyPlanToNextWeeks(CustomerActivityPlan record, int weeksNum) { // record数据是下周数据
		logger.debug("start copy CustomerActivityPlan " + CommonUtil.getCurrTimeForString()
				+ " weekNum " + weeksNum);
		List dataList = new ArrayList<>();
		Date dateTemp = null;
		if (record.getDetails() != null && record.getDetails().size() != 0) {
			for (CustomerActivityPlanServiceItemDetail detail : record.getDetails()) {
				if (detail != null && detail.getDelStatus() != null && detail.getDelStatus() != 1) {
					for (int i = 0; i < weeksNum + 2; i++) {
						if (i == 0) {
							dateTemp = new Date();// 本周 已经存在 i=1是下周 2 3 4为后三周
						}
						int weekIndex = CommonUtil.getWeekIndexFromSun(dateTemp);
						int year = dateTemp.getYear() + 1900;// 产生下三周的 年 周 序号
						dateTemp = CommonUtil.getNextSaturday(dateTemp, 1);// 下周6的时间
						if (i > 1) {
							CustomerActivityPlanServiceItemDetail data = new CustomerActivityPlanServiceItemDetail();
							data.setCreateDateTime(CommonUtil.getCurrTimes());
							data.setCustomer(detail.getCustomer());
							data.setItem(detail.getItem());
							data.setDelStatus((short) 0);
							data.setStartTimeTab(detail.getStartTimeTab());
							data.setTenant(detail.getCustomer().getTenant());
							data.setWeekTab(detail.getWeekTab());// 周几
							data.setWeekIndex(weekIndex);// 第几周
							data.setYearTab(year);
							dataList.add(data);
						}
					}
				}
			}
			if (dataList.size() > 0) {
				commonService.batchInsert(dataList); // 复制到后三周
			}
		}
	}

	/**
	 * 根据CustomerNursingPlanModel复制产生当日护理计划
	 */
	public void copyPlanToToday(CustomerActivityPlanModel model, Long id) {
		logger.info("start copy CustomerActivityPlanServiceItemModel PlanToToday "
				+ CommonUtil.getCurrTimeForString());
		List<CustomerActivityPlanServiceItemDetail> dataList = new ArrayList<>();
		Date dateTemp = new Date();
		int weekIndex = CommonUtil.getWeekIndexFromSun(dateTemp);
		int year = dateTemp.getYear() + 1900;// 产生 年 周 序号
		int weekTab = CommonUtil.getWeek(dateTemp);
		int monthTab = dateTemp.getDate();
		int monthIndex = dateTemp.getMonth();

		// 验证当天护理计划是否被执行过
		int copyNowFlag = checkPlanDetailNowRelations(id, year, weekIndex, weekTab);
		if (copyNowFlag > 0) {
			throw new BusinessException(null, CommonConstants.ERROR_CODE.REPEAT_ERROR.label(), null);
		}

		if (model.getItems() != null && model.getItems().size() != 0) {
			for (CustomerActivityPlanServiceItem item : model.getItems()) {
				if (item != null && item.getDelStatus() != null && item.getDelStatus() != 1) {
					CustomerActivityPlanServiceItemDetail data = new CustomerActivityPlanServiceItemDetail();
					data.setCreateDateTime(CommonUtil.getCurrTimes());
					data.setCustomer(item.getCustomer());
					data.setItem(item.getItem());
					data.setDelStatus((short) 0);
					data.setStartTimeTab(item.getStartTimeTab());
					data.setTenant(item.getTenant());
					data.setWeekTab(weekTab);// 周几
					data.setWeekIndex(weekIndex);// 第几周
					data.setMonthIndex(monthIndex);
					data.setMonthTab(monthTab);
					data.setYearTab(year);

					if (item.getWeekTab() != null && item.getWeekTab() == weekTab) {// 周计划
						dataList.add(data);
					} else if (item.getMonthTab() != null && item.getMonthTab() == monthTab) { // 月计划
						dataList.add(data);
					} else if (item.getWeekTab() == null && item.getMonthTab() == null) { // 日计划每天都有
						dataList.add(data);
					}
				}
			}
			if (dataList.size() > 0) {
				commonService.batchInsert(dataList);
			}
		}
	}

	/**
	 * 判断当日护理计划 是否被执行
	 */
	@Transactional
	public void checkPlanToToday(CustomerActivityPlanModel model) {
		if (true) {
			throw new BusinessException(null, CommonConstants.ERROR_CODE.REPEAT_ERROR.label(), null);
		}
		Date dateTemp = new Date();
		if (model.getItems() != null && model.getItems().size() != 0) {
			for (CustomerActivityPlanServiceItem item : model.getItems()) {
				if (item != null && item.getDelStatus() != null && item.getDelStatus() != 1) {
					int weekIndex = CommonUtil.getWeekIndexFromSun(dateTemp);
					int year = dateTemp.getYear() + 1900;// 产生 年 周 序号
					int weekTab = CommonUtil.getWeek(dateTemp);

					// 验证当天护理计划是否被执行过
					int copyNowFlag = checkPlanDetailNowRelations(item.getCustomer().getId(), year,
							weekIndex, weekTab);
					if (copyNowFlag > 0) {
						throw new BusinessException(null,
								CommonConstants.ERROR_CODE.REPEAT_ERROR.label(), null);
					}
				}
			}
		}
	}

	/**
	 * 复制产生未来几周护理计划
	 */
	public void copyPlanToNextWeeks(CustomerActivityPlanModel model, int weeksNum) {
		logger.debug("start copy CustomerNursingPlanModel " + CommonUtil.getCurrTimeForString()
				+ " weekNum " + weeksNum);
		List dataList = new ArrayList<>();
		Date dateTemp = null;
		if (model.getItems() != null && model.getItems().size() != 0) {
			for (CustomerActivityPlanServiceItem item : model.getItems()) {
				if (item != null && item.getDelStatus() != null && item.getDelStatus() != 1) {
					for (int i = 0; i <= weeksNum; i++) {
						if (i == 0) {
							dateTemp = new Date();// i=0 本周 不复制 i=1是下周 2 3 4为后三周
						}
						int weekIndex = CommonUtil.getWeekIndexFromSun(dateTemp);
						int year = dateTemp.getYear() + 1900;// 产生 年 周 序号
						int weekTab = CommonUtil.getWeek(dateTemp);
						dateTemp = CommonUtil.getNextSaturday(dateTemp, 1);// 下周6的时间
						// 复制本周护理计划
						if (i == 0) {
							// 验证当天护理计划是否被执行过
							int copyNowFlag = checkPlanDetailNowRelations(item.getCustomer()
									.getId(), year, weekIndex, weekTab);
							if (item.getWeekTab() != null && item.getWeekTab() >= weekTab) {// 周计划
								int copyFlag = 1;
								// 当天已有计划被执行过不复制
								if (item.getWeekTab() == weekTab && copyNowFlag != 0) {
									copyFlag = 0;
								}
								if (copyFlag == 1) {
									CustomerActivityPlanServiceItemDetail data = new CustomerActivityPlanServiceItemDetail();
									data.setCreateDateTime(CommonUtil.getCurrTimes());
									data.setCustomer(item.getCustomer());
									data.setItem(item.getItem());
									data.setDelStatus((short) 0);
									data.setStartTimeTab(item.getStartTimeTab());
									data.setTenant(item.getTenant());
									data.setWeekTab(item.getWeekTab());// 周几
									data.setWeekIndex(weekIndex);// 第几周
									data.setYearTab(year);
									dataList.add(data);
								}
							}
							if (item.getWeekTab() == null) { // 日计划每天都有
								int k = weekTab + 1;
								if (copyNowFlag == 0) {
									k = weekTab;
								}
								for (; k < 7; k++) {
									CustomerActivityPlanServiceItemDetail data = new CustomerActivityPlanServiceItemDetail();
									data.setCreateDateTime(CommonUtil.getCurrTimes());
									data.setCustomer(item.getCustomer());
									data.setItem(item.getItem());
									data.setDelStatus((short) 0);
									data.setStartTimeTab(item.getStartTimeTab());
									data.setTenant(item.getTenant());
									data.setWeekTab(k);// 周几
									data.setWeekIndex(weekIndex);// 第几周
									data.setYearTab(year);
									dataList.add(data);
								} // end for k
							}
						}
						// 复制未来周护理计划
						if (i > 0) {
							if (item.getWeekTab() != null) {// 周计划
								CustomerActivityPlanServiceItemDetail data = new CustomerActivityPlanServiceItemDetail();
								data.setCreateDateTime(CommonUtil.getCurrTimes());
								data.setCustomer(item.getCustomer());
								data.setItem(item.getItem());
								data.setDelStatus((short) 0);
								data.setStartTimeTab(item.getStartTimeTab());
								data.setTenant(item.getTenant());
								data.setWeekTab(item.getWeekTab());// 周几
								data.setWeekIndex(weekIndex);// 第几周
								data.setYearTab(year);
								dataList.add(data);
							} else { // 日计划每天都有
								for (int k = 0; k < 7; k++) {
									CustomerActivityPlanServiceItemDetail data = new CustomerActivityPlanServiceItemDetail();
									data.setCreateDateTime(CommonUtil.getCurrTimes());
									data.setCustomer(item.getCustomer());
									data.setItem(item.getItem());
									data.setDelStatus((short) 0);
									data.setStartTimeTab(item.getStartTimeTab());
									data.setTenant(item.getTenant());
									data.setWeekTab(k);// 周几
									data.setWeekIndex(weekIndex);// 第几周
									data.setYearTab(year);
									dataList.add(data);
								} // end for k
							}
						} // end if i
					} // end for i
				} // end if item
			}
			if (dataList.size() > 0) {
				commonService.batchInsert(dataList); // 复制到后4周
			}
		}
	}

	/**
	 * 验证projectitem是否和plandetail有关联
	 */
	public int checkProjectItemRelations(Customer customer, List<Long> itemIds, int dateTime) {

		List modelList = new ArrayList<>(); // 检查护理模版是否包含
		StringBuilder queryDetail = new StringBuilder(
				"select n from NursingPlanServiceItem n where n.delStatus != ?1 and n.customer.id = ?2  and n.item.id in (:ids) ");
		modelList = this.em.createQuery(queryDetail.toString()).setParameter(1, (short) 1)
				.setParameter(2, customer.getId()).setParameter("ids", itemIds).getResultList();

		return modelList.size();
	}


	/**
	 * 获取 老人 活动计划
	 */
	public List<CustomerActivityCompareService> getActivityServiceByCustomer(Long customerId, Long userId,
			Long queryStartDate, Long queryEndDate) {
		String curTime = CommonUtil.getCurrTimeForString();// 当日日期
		Integer curTimeStart = 0;
		Integer curTimeEnd = 0;
		try {
			curTimeStart = CommonUtil.strToIntegerTime(curTime.substring(0, 10) + " 00:00:00");
			curTimeEnd = CommonUtil.strToIntegerTime(curTime.substring(0, 10) + " 23:59:59");
		} catch (ParseException e) {
			logger.error("timer error " + e);
		}
		
		List<CustomerActivityPlanServiceItemDetail> detailList = new ArrayList<CustomerActivityPlanServiceItemDetail>();// 护理计划
		List<CustomerActivityPlanExecute> detailExeList = new ArrayList<CustomerActivityPlanExecute>();// 定时任务完成情况
		Map<String, List<CustomerActivityPlanExecute>> planExeMap = new HashMap<>();// projextItemid+执行情况/projextItemid+#+planexedate+执行情况
		List<Long> customerList3 = new ArrayList<>();
		if (customerId != null) {
			customerList3.add(customerId);
		} else {
			// 所有老人
			customerList3 = getCustomerByUID(userId, CommonUtil.getCurrTimes());
		}
		List<Long> customerList2 = new ArrayList<>();
		for(Long id : customerList3) {
			// 判断老人是否请假
			Map<String, Object> params = Maps.newHashMap();
			params.put("customer.id", id);
			params.put("status", LeaveStatus.LEAVING.getValue());
			params.put("delStatus", CommonConstants.DEL_STATUS_NO_0);
			String querySb = buildQueryStr(params, "CustomerLeave");
			List<CustomerLeave> list = this.em.createQuery(querySb).getResultList();
			if(!(list != null && list.size() > 0)) {
				customerList2.add(id);
			} 
		}
		
		List<CustomerActivityCompareService> dataList = new ArrayList<CustomerActivityCompareService>();
		if(customerList2.size() == 0) {
			return dataList;
		}
		
		if (customerList2 != null && customerList2.size() > 0) {
			Long idTemp = (long) 1;
			detailList = getCustomerActivityPlanServiceItemDetailByCustomer(customerList2);
			// 获取当日任务planexe执行情况
			StringBuilder queryDetailExe = new StringBuilder("select c from CustomerActivityPlanExecute c "
					+ " where c.delStatus != ?1  and c.itemProject.project.customer.id in (:olds) "
					+ " and c.createDateTime >= ?3 and c.createDateTime <= ?4 ");
			detailExeList = this.em.createQuery(queryDetailExe.toString())
					.setParameter(1, (short) 1).setParameter("olds", customerList2)
					.setParameter(3, curTimeStart).setParameter(4, curTimeEnd).getResultList();
			// 拼接map,key:projextItemid(不定时)/projextItemid+#+planexedate(定时)
			if (detailExeList != null && detailExeList.size() > 0) {
				for (int i = 0; i < detailExeList.size(); i++) {
					if (detailExeList.get(i).getPlanExeDate() != null
							&& detailExeList.get(i).getPlanExeDate().matches("\\d+")) {// 定时任务执行
						List<CustomerActivityPlanExecute> exes = new ArrayList<>();
						exes.add(detailExeList.get(i));
						planExeMap.put(detailExeList.get(i).getItemProject().getId().toString()
								+ "#" + detailExeList.get(i).getPlanExeDate(), exes);
					} else {
						if (planExeMap
								.get(detailExeList.get(i).getItemProject().getId().toString()) == null) {//
							List<CustomerActivityPlanExecute> exes = new ArrayList<>();
							exes.add(detailExeList.get(i));
							planExeMap.put(
									detailExeList.get(i).getItemProject().getId().toString(), exes);
						} else {
							planExeMap
									.get(detailExeList.get(i).getItemProject().getId().toString())
									.add(detailExeList.get(i));
						}
					}
				}
			}
			for (CustomerActivityPlanServiceItemDetail detail : detailList) {
				if (detail != null && detail.getStartTimeTab() != null
						&& !"".equals(detail.getStartTimeTab())) {
					CustomerActivityCompareService temp = new CustomerActivityCompareService();
					if (planExeMap.containsKey(detail.getItem().getId().toString() + "#"
							+ detail.getStartTimeTab())) {
						temp.setItemExes(planExeMap.get(detail.getItem().getId().toString() + "#"
								+ detail.getStartTimeTab()));
					}
					temp.setId(idTemp);
					temp.setItem(detail);
					dataList.add(temp);
					idTemp++;
				}
			}
			// 按照时间排序
			Collections.sort(dataList);
		} // end if culist
		return dataList;
	}
	
	/**
	 * 构建查询语句
	 *
	 * @author ytche
	 * @param param
	 * @return
	 * @date 2017年6月16日 下午4:48:09
	 */
	private String buildQueryStr(Map<String, Object> param, String name) {
		StringBuilder querySb = new StringBuilder("from ").append(name).append(
				" as t ");
		if (param == null || param.size() < 1) {
			return querySb.toString();
		}
		querySb.append(" where ");
		int index = 0;
		for (Entry<String, Object> entry : param.entrySet()) {
			if (index != 0) {
				querySb.append(" and ");
			}
			querySb.append(" t.").append(entry.getKey()).append("='")
					.append(entry.getValue()).append("' ");
			index++;
		}
		return querySb.toString();
	}

	/**
	 * 根据user对应employee所当天以及昨天跨天排班获取user照料老人 区分职位 user->employee employee +
	 * StaffSchedule-> workTimeSetting workTimeSetting + BedWorkTimeSetting ->
	 * bed bed -> customer
	 */
	public List<Long> getCustomerByUID(long userId, Integer dateTime) {
		List<Long> customerList = new ArrayList<>();
		StringBuilder queryCustomer = new StringBuilder();
		// 所有老人
		queryCustomer
		.append("select c.id from Customer c where c.delStatus != 1 and  c.customerStatus is not null"
				+ " and (c.customerStatus.typecode=?1 or c.customerStatus.typecode=?2 or c.customerStatus.typecode=?4)"
				+ " and c.tenant in (select u.tenant from User u where u.id = ?3 )");
		customerList = this.em.createQuery(queryCustomer.toString())
				.setParameter(1, "customerStatusIn").setParameter(2, "customerStatusTry")
				.setParameter(3, userId).setParameter(4, "customerStatusTryWaitIn")
				.getResultList();

		return customerList;
	}

	/**
	 * 新增执行情况，如为增值服务生成增值服务账单
	 */
	@Transactional
	public void addPlanExe(CustomerActivityPlanExecute exe) {
		Customer customer = exe.getItemProject().getCustomer();
		exe.setRecorder(customer);
		// 执行信息存储
		dslJpaService.setEntityClass(CustomerActivityPlanExecute.class);
		if (exe.getId() == null) {
			dslJpaService.create(exe);
		} else {
			dslJpaService.update(exe);
		}
	}

	/**
	 * 添加时间
	 * @param startTime 带毫秒的时间格式--yyyy-MM-dd HH:mm:ss
	 * @param minute 整数，添加时间
	 * @return
	 * @throws Exception
	 */
	public static String plusTime(String startTime, int minute) throws Exception {
		SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
		Date date = new Date(parseLongTime(startTime) + (minute * 60 * 1000));
		return sdf.format(date);
	}
	public static long plusTimeLong(String startTime, int minute) throws Exception {
		return parseLongTime(startTime) + (minute * 60 * 1000);
	}

	/**
	 * 将时间转换成毫秒 参数格式-- yyyy-MM-dd HH:mm:ss.S
	 * @param time
	 * @return
	 * @throws Exception
	 */
	public static long parseLongTime(String time) throws Exception {
		SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
		Date date = sdf.parse(time);
		return date.getTime();
	}

	/**
	 * 获取老人对应的护理组Staff
	 */
	public List<Employee> getEmployeeByCID(long customerId) {
		StringBuilder queryEmployee = new StringBuilder(
				" select en.employee from EmployeeNursingGroup en where en.delStatus != 1 and en.group in "
						+ " ( select bn.group from BedNurseGroup bn where bn.delStatus != 1 and bn.bed in (select c.bed from Customer c where c.delStatus != 1 and c.id=?1) ) ");
		List<Employee> staffList = this.em.createQuery(queryEmployee.toString())
				.setParameter(1, customerId).getResultList();
		return staffList;
	}

	/**
	 * 产生护理项目标签随机产生remark
	 *
	 * @author huibati
	 * @param 2017年9月9日
	 */
	public ServiceFinishLevel createServiceFinishLevel(ServiceFinishLevel data) {
		StringBuilder query = new StringBuilder(
				" select en from ServiceFinishLevel en where en.delStatus != 1 and en.item.id =?1 and en.remark = ?2 ");
		String code = "";
		while (true) {
			code = "c" + CommonUtil.buildRandom(8);
			List<ServiceFinishLevel> dataList = this.em.createQuery(query.toString())
					.setParameter(1, data.getItem().getId()).setParameter(2, code).getResultList();
			if (dataList == null || dataList.size() == 0) {
				data.setRemark(code);
				break;
			}
		}
		dslJpaService.setEntityClass(ServiceFinishLevel.class);
		dslJpaService.create(data);
		return data;
	}

	/**
	 * 获取服务项目
	 */
	public CustomerActivityServiceItem getCustomerActivityServiceItemById(Long id) {
		StringBuilder query = new StringBuilder(
				"select c from CustomerActivityServiceItem c where c.id = ?1 ");
		List dataList = this.em.createQuery(query.toString()).setParameter(1, id).getResultList();
		CustomerActivityServiceItem ct = null;
		if (dataList.size() > 0) {
			ct = (CustomerActivityServiceItem) dataList.get(0);
		}
		return ct;
	}
	
	/**
	 * 删除护理计划模版 弃用
	 */
	@Transactional
	public void deletePlanItem(CustomerActivityPlan record) {
		// 删除原有数据
		List customers = getCustomersFromCustomerNursingPlan(record);
		if (record.getDetails() != null && record.getDetails().size() > 0 && customers.size() > 0) {
			StringBuilder query = new StringBuilder(
					"delete from  CustomerActivityPlanServiceItem c  where c.customer is not null and c.customer in (:olds)");
			this.em.createQuery(query.toString()).setParameter("olds", customers).executeUpdate();
		}
	}
	
	/**
	 * 获取老人 CustomerActivityPlanServiceItemDetail 活动计划
	 */
	public List<CustomerActivityPlanServiceItemDetail> getCustomerActivityPlanServiceItemDetailByCustomer(List<Long> customerList) {
		List<CustomerActivityPlanServiceItemDetail> dataList = new ArrayList<CustomerActivityPlanServiceItemDetail>();
		if (customerList != null && customerList.size() > 0) {
			Date now = new Date();
			Integer weekIndex = CommonUtil.getWeekIndexFromSun(now);// test
			Integer year = now.getYear() + 1900;
			Integer week = CommonUtil.getWeek(now);
			// 获取老人对应的 CustomerActivityPlanServiceItemDetail
			StringBuilder queryDetail = new StringBuilder(
					"select c from CustomerActivityPlanServiceItemDetail c "
							+ " where c.delStatus != ?1 and c.item.item.delStatus!=1 "
							+ " and c.yearTab=?2 and c.weekIndex=?3 and c.weekTab=?4 and c.customer.id in (:olds)");
			dataList = this.em.createQuery(queryDetail.toString()).setParameter(1, (short) 1)
					.setParameter(2, year).setParameter(3, weekIndex).setParameter(4, week)
					.setParameter("olds", customerList).getResultList();
		}
		return dataList;
	}

	/**
	 * 获取customer 的 定时服务项目
	 */
	public Iterable<CustomerActivityPlanServiceItemDetail> getTimeServiceItemByCID(long customerId) {
		List<CustomerActivityPlanServiceItemDetail> dataList = new ArrayList<CustomerActivityPlanServiceItemDetail>();
		if (ActionContextHolder.getContext().getUser() != null
				&& ActionContextHolder.getContext().getUser().getId() != null) {
			Date now = new Date();
			Integer weekIndex = CommonUtil.getWeekIndexFromSun(now);// test
			Integer year = now.getYear() + 1900;
			Integer week = CommonUtil.getWeek(now);
			List<Long> customerList = new ArrayList<>();
			customerList.add(customerId);
			if (customerList.size() > 0) {
				// 获取当前护工所护理老人对应的 NursingPlanServiceItem
				StringBuilder queryDetail = new StringBuilder(
						"select c from CustomerActivityPlanServiceItemDetail c "
								+ "where c.delStatus != ?1 and c.item.project.delStatus!=1 and c.yearTab=?2 and c.weekIndex=?3 and c.weekTab=?4 and c.customer.id in(:olds) ");
				dataList = this.em.createQuery(queryDetail.toString()).setParameter(1, (short) 1)
						.setParameter(2, year).setParameter(3, weekIndex).setParameter(4, week)
						.setParameter("olds", customerList).getResultList();
			}
		}
		return dataList;
	}
	
	/**
	 * 扫码 直接获取 customer projectitem
	 */
	public Iterable<CustomerActivityProjectItem> getCustomerProjectItem(long customerId) {
		List<CustomerActivityProjectItem> itemList = new ArrayList<CustomerActivityProjectItem>();
		if (ActionContextHolder.getContext().getUser() != null
				&& ActionContextHolder.getContext().getUser().getId() != null) {
			List<Long> customerList = new ArrayList<>();
			customerList.add(customerId);
			if (customerList.size() > 0) {
				// 获取老人对应的 NursingProjectServiceItem 通过角色类型进行过滤
				StringBuilder queryItem = new StringBuilder(
						"select item from NursingProjectServiceItem item JOIN FETCH item.project project "
								+ "where item.delStatus != ?1 and project.customer.id in(:olds) ");
				itemList = this.em.createQuery(queryItem.toString())
						.setParameter(1, (short) 1).setParameter("olds", customerList)
						.getResultList();
			}
		}
		return itemList;
	}
	

	/**
	 * 护理计划是否执行过
	 */
	public int checkPlanDetailExeRelations(CustomerActivityPlanServiceItemDetail data) {
		StringBuilder queryNow = new StringBuilder(
				"select c from  CustomerActivityPlanExecute c where c.delStatus!=1 and c.detail is not null  "
						+ " and c.detail.id =?1  ");
		List dataList = this.em.createQuery(queryNow.toString()).setParameter(1, data.getId())
				.getResultList();
		if (dataList == null || dataList.size() == 0) {
			return 0;
		} else
			return dataList.size();
	}
	

	/**
	 * @author huibati 删除任务执行情况planexe
	 */
	@Transactional
	public void deleteNursingPlanExecute(CustomerActivityPlanExecute exe) {
		StringBuilder deleteExe = new StringBuilder(
				"update  CustomerActivityPlanExecute rp set rp.delStatus=1 where rp.id = ?1  ");
		this.em.createQuery(deleteExe.toString()).setParameter(1, exe.getId()).executeUpdate();
	}
	

	/**
	 * 获取时间点之后的老人plandetail对应的projectitem
	 */
	public List<CustomerActivityProjectItem> getProjectItemFromCustomerActivityPlanDetail(long customerId,
			int dateTime) {
		Date now = new Date(dateTime * 1000l);
		Integer weekIndex = CommonUtil.getWeekIndexFromSun(now);
		Integer yearTab = now.getYear() + 1900;
		Integer weekTab = CommonUtil.getWeek(now);
		if (weekTab == 0) {
			weekTab = 7;
		}
		/*
		 * StringBuilder query = new StringBuilder(
		 * "select distinct c.item from NursingPlanDetail c where c.delStatus != ?1 and c.item is not null and c.customer.id=?2"
		 * + " and (" +
		 * "  ( c.yearTab<?3 ) or ( c.yearTab=?3 and c.weekIndex < ?4  ) or ( c.yearTab=?3 and c.weekIndex = ?4 and c.weekTab <=?5 ) "
		 * + " )"); List<NursingProjectServiceItem> dataList =
		 * this.em.createQuery(query.toString()) .setParameter(1, (short)
		 * 1).setParameter(2, customerId).setParameter(3, yearTab)
		 * .setParameter(4, weekIndex).setParameter(5, weekTab).getResultList();
		 */
//		StringBuilder query = new StringBuilder(
//				"select distinct c.item from CustomerActivityProjectItem c where c.delStatus != ?1 and c.item is not null and c.customer.id=?2");
//		List<CustomerActivityProjectItem> dataList = this.em.createQuery(query.toString())
//				.setParameter(1, (short) 1).setParameter(2, customerId).getResultList();
//		return dataList;
		
		StringBuilder query = new StringBuilder(
				"select distinct c.item from CustomerActivityPlanServiceItem c where c.delStatus != ?1 and c.item is not null and c.customer.id=?2");
		List<CustomerActivityProjectItem> dataList = this.em.createQuery(query.toString())
				.setParameter(1, (short) 1).setParameter(2, customerId).getResultList();
		return dataList;
	}
	
}
